package layers.ants;

import layers.agents.TruckAgent;
import layers.physical.Crossroad;
import layers.physical.Path;
import layers.physical.Road;

public abstract class ExplorationAntState {

	private ExplorationAnt ant;

	public ExplorationAntState(ExplorationAnt ant){
		if(ant == null)
			throw new IllegalArgumentException("Ant cannot be null.");
		this.ant = ant;
	}

	protected ExplorationAnt getAnt(){
		return this.ant;
	}

	protected void clearAnt(){
		this.ant = null;
	}

	protected void dropMark(int truckId, Crossroad crossroad) {
		Mark mark = new Mark(truckId, this.getAnt().getRemainingHops(), this.getAnt().getTraveledDistance());
		crossroad.dropExplorationAntMark(mark);
	}

	protected void followRoadSigns(Road road, int truckId, Crossroad crossroad){
		dropMark(truckId, crossroad);
		Crossroad nextCrossroad = road.getOtherConnector(crossroad);
		this.getAnt().setCrossroad(nextCrossroad);
		this.getAnt().setRoadLastTraveled(road);
	}

	protected abstract void processTick();

	protected void notifyTruck(){
		throw new UnsupportedOperationException();
	}

	protected void cloneExplorationAnt() {
		for(Road road : this.getAnt().getCrossroad().getOutgoingConnections()){
			Crossroad nextCrossroad = road.getOtherConnector(this.getAnt().getCrossroad());
			if(!this.getAnt().getPath().contains(nextCrossroad) && !nextCrossroad.containsBetterExplorationMark(this.getAnt().getAgent().getId(), this.getAnt().getTraveledDistance() + road.getLength())){
				ExplorationAnt ant = new ExplorationAnt(
						nextCrossroad, 
						(TruckAgent) this.getAnt().getAgent(),
						this.getAnt().getRemainingHops(), 
						this.getAnt().getTraveledDistance(),
						(Path) this.getAnt().getPath().getClone());
				ant.setRoadLastTraveled(road);
			}
		}
	}
}
